﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;

namespace WpfAppListView
{
    public class MyViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        protected virtual void OnPropertyChanged(System.Linq.Expressions.Expression<Func<object>> expression)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged._ExNotify(expression);
            }
        }

    }

    /// <summary>
    /// PropertyChanged  扩展
    /// </summary>
    public static class _ExINotifyPropertyChanged
    {
        /// <summary>
        /// this.PropertyChanged.Notify(() => this.PopertyName);
        /// </summary>
        /// <param name="eventHandler"></param>
        /// <param name="expression"></param>
        public static void _ExNotify(this System.ComponentModel.PropertyChangedEventHandler eventHandler, System.Linq.Expressions.Expression<Func<object>> expression)
        {
            if (null == eventHandler)
            {
                return;
            }

            var lambda = expression as System.Linq.Expressions.LambdaExpression;
            System.Linq.Expressions.MemberExpression memberExpression;
            if (lambda.Body is System.Linq.Expressions.UnaryExpression)
            {
                var unaryExpression = lambda.Body as System.Linq.Expressions.UnaryExpression;
                memberExpression = unaryExpression.Operand as System.Linq.Expressions.MemberExpression;
            }
            else
            {
                memberExpression = lambda.Body as System.Linq.Expressions.MemberExpression;
            }
            var constantExpression = memberExpression.Expression as System.Linq.Expressions.ConstantExpression;
            var propertyInfo = memberExpression.Member as System.Reflection.PropertyInfo;


            foreach (var del in eventHandler.GetInvocationList())
            {
                del.DynamicInvoke(new object[] { constantExpression.Value, new System.ComponentModel.PropertyChangedEventArgs(propertyInfo.Name) });
            }
        }


       
        /// <summary>
        /// 获取属性名称
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static string GetPropertyName<TSource, TResult>(System.Linq.Expressions.Expression<Func<TSource, TResult>> expression)
        {
            if (expression.NodeType == System.Linq.Expressions.ExpressionType.Lambda && expression.Body.NodeType == System.Linq.Expressions.ExpressionType.MemberAccess)
            {

                System.Reflection.PropertyInfo prop = (expression.Body as System.Linq.Expressions.MemberExpression).Member as System.Reflection.PropertyInfo;
                if (prop != null)
                {
                    return prop.Name;
                }
            }
            throw new ArgumentException("expression", "Not a property expression");
        }


    }

}
